﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections.Specialized;

namespace EnCor.Security
{
    public class CustomAuthenticationProviderAssembler : AuthenticationProviderAssembler
    {
        public override IAuthenticationProvider Assemble(ObjectBuilder.IBuilderContext context, AuthenticationProviderConfig objectConfiguration)
        {
            CustomAuthenticationProviderConfig config = objectConfiguration as CustomAuthenticationProviderConfig;
            if (config == null)
            {
                throw new EnCorException(string.Format("Config type {0} can not be used to build {1}", objectConfiguration, objectConfiguration.Type));
            }

            if (config.Type == null)
            {
                throw new EnCorException(string.Format("Cannot load type {0}", config.TypeName));
            }

            if (!typeof(IAuthenticationProvider).IsAssignableFrom(config.Type))
            {
                throw new EnCorException(string.Format("Type {0} does not implement the interface IAuthenticationProvider.", config.Type));
            }

            ConstructorInfo constructor = null;

            foreach (ConstructorInfo c in config.Type.GetConstructors())
            {
                ParameterInfo[] parameters = c.GetParameters();
                if (parameters.Length == 1 && parameters[0].ParameterType == typeof(NameValueCollection))
                {
                    constructor = c;
                    break;
                }
            }

            if (constructor == null)
            {
                throw new EnCorException(string.Format("The type {0} does not have a constructor with parameter NameValueCollection.", config.Type));
            }

            return constructor.Invoke(new object[] { config.Parameters }) as IAuthenticationProvider;
        }
    }
}
